pub fn use_enum(){
    print();
    use_diff_type();
    use_match_with_enum();
    use_match_enum_tuple();
    use_option();
}


#[derive(Debug)]
enum Book{
    Papery,
    Electronic
}

fn print(){
    let book = Book::Papery;
    println!("book is :{:?}", book);
    let ebook = Book::Electronic;
    println!("book is :{:?}", ebook);
}


#[derive(Debug)]
enum DiffBook{
    Papery(u32), 
    Electronic(String), 
}


fn use_diff_type(){
    let book = DiffBook::Papery(1001);
    println!("book is :{:?}", book);
    let ebook = DiffBook::Electronic(String::from("http://hello.pdf"));
    println!("ebook is :{:?}", ebook);
}

enum NamedBook {
    Papery{index: u32},
    Electronic { url: String},
}


fn use_match_with_enum(){
    fn match_book(book : &NamedBook ){
        match book {
            NamedBook::Papery { index } => {
                println!("Papery book {}", index);
            },
            NamedBook::Electronic{ url} => {
                println!("Electronic book {}", url);
            }
        }
    }
    fn match_book_return(book : &NamedBook) -> u32{
        let ret = match book {
            NamedBook::Papery{ index: _ }  =>  1,
            NamedBook::Electronic{ url: _ } => 2,
        };
        return ret;
    }
    let book = NamedBook::Papery{index: 10001};
    match_book(&book);
    println!("ret : {}", match_book_return(&book));

    let ebook = NamedBook::Electronic{ url: String::from("url://....") };
    match_book(&ebook);
    println!("ret : {}", match_book_return(&ebook));
}

fn use_match_enum_tuple(){
    enum Book {
        Papery(u32),
        Electronic {url: String},
    }
    let book = Book::Papery(1001);
    match &book {
        Book::Papery(i) => { // Note: i is tmp named
            println!("{}", i);
        },
        Book::Electronic { url } => {
            println!("{}", url);
        }
    }
    
    // if let 0 == i
    if let Book::Papery(i) = book {
        println!("Papery: {}", i);
    } else{
        println!("not Papery book");
    }


    let ebook = Book::Electronic{ url: String::from("url:///.....") };
    match ebook {
        Book::Papery(i) => { // Note: i is tmp named
            println!("{}", i);
        },
        Book::Electronic { url } => {
            println!("{}", url);
        }
    }


    // use the plain type 
    let t = "abc";
    match t {
        "abc" => println!("string:{}", t),
        _ => {},
    }


}

//Option is internal enum
fn use_option(){
    fn match_opt(opt: &Option<&str>){
        match &opt {
            Option::Some(something) => {
                println!("opt value is : {}", something);
            },
            Option::None => {
                println!("opt is null!");
            }
        }
    }
    let opt = Option::Some("Hello");
    match_opt(&opt);

    let opt: Option<&str> = Option::None;
    match_opt(&opt);
}
